﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace VirtualKeyboard.Controls
{
    public partial class IPBox
    {
        public static readonly DependencyProperty IPAddressProperty =
            DependencyProperty.Register("IPAddress", typeof(string), typeof(IPBox),
            new PropertyMetadata(String.Empty, IPPropertyChangedCallback));

        private static void IPPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs arg)
        {
            var value = (string)arg.NewValue;
            if (string.IsNullOrWhiteSpace(value)) return;
            var ipBox = (IPBox)sender;
            ipBox.SetIPAddress(value);
        }

        [Description("获取或设置IP")]
        [Category("Common Properties")]
        public string IPAddress
        {
            get { return (string)GetValue(IPAddressProperty); }
            set { SetValue(IPAddressProperty, value); }
        }

        private readonly TextBox[] textBoxs;
        private readonly string[] ipParts;

        public IPBox()
        {
            InitializeComponent();

            textBoxs = new[]
                           {
                               TextOctet1,
                               TextOctet2,
                               TextOctet3,
                               TextOctet4
                           };
            ipParts = new string[4];
            for (int i = 0; i < 4; i++)
            {
                var box = textBoxs[i];
                box.Tag = i;
                box.TextChanged += OnTextChanged;
                box.KeyDown += OnKeyDown;
            }
        }

        private void UpdateIPAddress()
        {
            for (int i = 0; i < 4; i++)
            {
                ipParts[i] = textBoxs[i].Text;
            }
            if (ipParts.Any(string.IsNullOrWhiteSpace)) return;
            IPAddress = string.Format("{0}.{1}.{2}.{3}", TextOctet1.Text, TextOctet2.Text, TextOctet3.Text,
                                      TextOctet4.Text);
        }

        private void SetIPAddress(string value)
        {
            IPAddress tmp;
            if (!System.Net.IPAddress.TryParse(value, out tmp)) return;

            string[] octets = value.Split('.');
            for (int i = 0; i < 4; i++)
            {
                if (ipParts[i] != octets[i])
                {
                    ipParts[i] = octets[i];
                    textBoxs[i].Text = octets[i];
                }
            }


        }

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            var textBox = (TextBox)sender;
            var index = (int)textBox.Tag;

            if (string.IsNullOrWhiteSpace(textBox.Text)) return;
            if (int.Parse(textBox.Text) > 255)
            {
                textBox.Text = "255";
                textBox.Select(3, 0);
            }

            if (ipParts[index] == textBox.Text) return;
            if (textBox.Text.Length == 3)
            {
                NextFocus(index);
            }
            UpdateIPAddress();
        }

        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            var textBox = (TextBox)sender;
            if (e.PlatformKeyCode == 190) //.
            {
                e.Handled = true;
                if (!string.IsNullOrEmpty(textBox.Text))
                {
                    NextFocus((int)textBox.Tag);
                }
                return;
            }
            if (e.Key == Key.Back)
            {
                if (string.IsNullOrEmpty(textBox.Text))
                {
                    e.Handled = true;
                    PrevFocus((int)textBox.Tag);
                }
            }
        }

        private void NextFocus(int index)
        {
            if (index >= 3) return;
            var box = textBoxs[index + 1];
            box.Focus();
            box.Select(box.Text.Length, 0);
        }

        private void PrevFocus(int index)
        {
            if (index < 1) return;
            var box = textBoxs[index - 1];
            box.Focus();
            box.Select(box.Text.Length, 0);
        }
    }
}
